package com.spring.demo.springdemo.config;

import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;

import java.util.Set;

/**
 * @Author RenPu
 * @Date 2024/2/18 15:36
 * @Version 1.0
 * @Description: 重写Spring的扫描BeanDefinition的逻辑，因为Spring扫描的对象过滤了接口
 *               Mybatis则是面向接口的，因此需要支持接口也可以生成BeanDefinition
 **/
public class MybatisBeanDefinitionScanner extends ClassPathBeanDefinitionScanner {

    public MybatisBeanDefinitionScanner(BeanDefinitionRegistry registry) {
        super(registry);
    }


    @Override
    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
        Set<BeanDefinitionHolder> beanDefinitionHolders = super.doScan(basePackages);

        for (BeanDefinitionHolder definitionHolder : beanDefinitionHolders) {
            BeanDefinition beanDefinition = definitionHolder.getBeanDefinition();

            //通过构造方法进行赋值
            beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(beanDefinition.getBeanClassName());
            beanDefinition.setBeanClassName(MybatisFactoryBeanConf.class.getName());
        }

        return beanDefinitionHolders;
    }

    /**
     * 设置扫描符合类型的条件，（此处设为满足为接口类型的都进行扫描）
     * @param beanDefinition
     * @return
     */
    @Override
    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
        return beanDefinition.getMetadata().isInterface();
    }
}
